package tool

import (
	consts2 "MoSkeleton/config/consts"
	"MoSkeleton/framework"
	"MoSkeleton/framework/core/consts"
	"MoSkeleton/framework/core/dto/response"
	"MoSkeleton/framework/utils"
	"MoSkeleton/global"
	"MoSkeleton/services"
	"MoSkeleton/web/pogos/request/tool"
	"MoSkeleton/web/v1/http/base"
	"fmt"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"time"
)

type CodeGenCtrl struct {
	base.BaseCtrl
}

func (g *CodeGenCtrl) GetCtrlTitle() string {
	msg, _ := utils.Translater.Translate(consts.TKey_TitleCodeGenMsg)
	return msg
}

func (g *CodeGenCtrl) UpdateCodeGen(c *gin.Context) {
	updateReq := new(tool.CodeGenUpdateReq)
	if err := c.ShouldBindJSON(updateReq); err != nil {
		global.MoLogger.Info("参数错误", zap.Error(err))
		response.FailMsgAsI18n(c, consts.ValidatorParamsCheckFailCode, consts.TKey_ValidatorParamsCheckFailMsg)
		return
	}
	updateReq.UpdatedBy = utils.GetUsernameFromGin(c)
	updateReq.ShouldBindParams(c)
	if err := services.ServiceGroupInst.ToolGroupInst.CodeGenServiceInst.ValidatorCodeGenUpdate(updateReq); err != nil {
		global.MoLogger.Info("参数错误", zap.Error(err))
		response.FailErrorWithCodeAsI18n(c, err, consts.ValidatorParamsCheckFailCode, consts.TKey_ValidatorParamsCheckFailMsg)
		return
	}
	if err := services.ServiceGroupInst.ToolGroupInst.CodeGenServiceInst.UpdateCodeGen(updateReq); err != nil {
		global.MoLogger.Info("更新代码生成失败", zap.Error(err))
		response.FailErrorWithCodeAsI18n(c, err, consts.CommUpdateFailCode, consts.TKey_CommUpdateFailMsg)
		return
	}
	response.SuccessAsI18n(c, consts.TKey_CommUpdateSuccessMsg, nil)
}

func (g *CodeGenCtrl) GetGenTablePage(c *gin.Context) {
	pageReq := new(tool.CodeGenPageReq)
	if err := c.ShouldBindQuery(pageReq); err != nil {
		framework.MoLogger.Error("获取代码生成列表失败", zap.Error(err))
		response.FailMsgAsI18n(c, consts.ValidatorParamsCheckFailCode, consts.TKey_ValidatorParamsCheckFailMsg)
		return
	}
	pageReq.ShouldBindParams(c)
	if pageResult, err := services.ServiceGroupInst.ToolGroupInst.CodeGenServiceInst.GetGenTablePage(pageReq); err != nil {
		framework.MoLogger.Error("获取代码生成列表失败", zap.Error(err))
		response.FailMsgAsI18n(c, consts.CommSelectFailCode, consts.TKey_CommonSelectListFailMsg)
		return
	} else {
		response.SuccessAsI18n(c, consts.TKey_CommonGetListSuccessMsg, pageResult)
	}
}

func (g *CodeGenCtrl) GetCodeGenDetail(c *gin.Context) {
	bizId := utils.StrToUint64Def(c.Param("bizId"), 0)
	tableId := utils.StrToUint64Def(c.Param("id"), 0)
	if bizId == 0 || tableId == 0 {
		framework.MoLogger.Error("无效的参数")
		response.FailMsgAsI18n(c, consts.ValidatorParamsCheckFailCode, consts.TKey_ValidatorParamsCheckFailMsg)
		return
	} else {
		if detail, err := services.ServiceGroupInst.ToolGroupInst.CodeGenServiceInst.GetCodeGenDetail(bizId, tableId); err != nil {
			framework.MoLogger.Error("获取代码生成详情失败", zap.Error(err))
			response.FailErrorWithCodeAsI18n(c, err, consts.CommSelectFailCode, consts.TKey_CommSelectFailMsg)
		} else {
			response.SuccessAsI18n(c, consts.TKey_CommGetSuccessMsg, detail)
		}
	}
}

func (g *CodeGenCtrl) GetDbTableList(c *gin.Context) {
	pageReq := &tool.DbTablePageReq{}
	bizId := utils.StrToUint64Def(c.Param("bizId"), 0)
	if err := c.ShouldBindQuery(pageReq); err != nil || bizId == 0 {
		framework.MoLogger.Error("获取数据表列表失败", zap.Error(err))
		response.FailMsgAsI18n(c, consts.ValidatorParamsCheckFailCode, consts.TKey_CommonSelectListFailMsg)
		return
	}
	pageReq.BizId = bizId
	pageReq.ShouldBindParams(c)
	codeGenServiceInst := services.ServiceGroupInst.ToolGroupInst.CodeGenServiceInst
	bizDb, err := codeGenServiceInst.GetGormDbByBizId(bizId)
	if err != nil {
		framework.MoLogger.Error("连接数据源失败", zap.Error(err))
		response.FailMsgAsI18n(c, consts.CommSelectFailCode, consts.TKey_GormDbConnFailMsg)
		return
	}
	if pageResult, err := codeGenServiceInst.GetDbTableList(bizDb, pageReq); err != nil {
		framework.MoLogger.Error("获取数据表列表失败", zap.Error(err))
		response.FailMsgAsI18n(c, consts.CommSelectFailCode, consts.TKey_CommonSelectListFailMsg)
		return
	} else {
		response.SuccessAsI18n(c, consts.TKey_CommonGetListSuccessMsg, pageResult)
	}
}

func (g *CodeGenCtrl) DeleteCodeGenByIds(c *gin.Context) {
	if ids, err := utils.TextToUint64s(c.Param("ids"), ","); err != nil {
		framework.MoLogger.Error("删除代码生成失败", zap.Error(err))
		response.FailMsgAsI18n(c, consts.ValidatorParamsCheckFailCode, consts.TKey_CommDeleteFailMsg)
		return
	} else {
		if err := services.ServiceGroupInst.ToolGroupInst.CodeGenServiceInst.DeleteCodeGenByIds(ids); err != nil {
			framework.MoLogger.Error("删除代码生成失败", zap.Error(err))
			response.FailErrorWithCodeAsI18n(c, err, consts.CommDeleteFailCode, consts.TKey_CommDeleteFailMsg)
		} else {
			response.SuccessAsI18n(c, consts.TKey_CommDeleteSuccessMsg, nil)
		}
	}
}

func (g *CodeGenCtrl) SaveImportTable(c *gin.Context) {
	importTableReq := &tool.ImportTableReq{}
	if err := c.ShouldBindQuery(importTableReq); err != nil {
		framework.MoLogger.Error("导入表失败", zap.Error(err))
		response.FailMsgAsI18n(c, consts.ValidatorParamsCheckFailCode, consts.TKey_GormImportTableFailMsg)
		return
	}
	importTableReq.BizId = utils.StrToUint64Def(c.Param("bizId"), 0)
	username := utils.GetUsernameFromGin(c)
	if err := services.ServiceGroupInst.ToolGroupInst.CodeGenServiceInst.SaveImportTable(importTableReq, username); err != nil {
		framework.MoLogger.Error("导入表失败", zap.Error(err))
		response.FailMsgAsI18n(c, consts.CommSelectFailCode, consts.TKey_GormImportTableFailMsg)
		return
	}
	response.SuccessAsI18n(c, consts.TKey_GormImportTableSuccessMsg, nil)
}

// TODO
func (g *CodeGenCtrl) DownloadByTable(c *gin.Context) {
	tableName := c.Param("tableName")

	services.ServiceGroupInst.ToolGroupInst.CodeGenServiceInst.DownloadByTable(tableName)
}

func (g *CodeGenCtrl) BatchGenCode(c *gin.Context) {
	bizId := utils.StrToUint64Def(c.Param("bizId"), 0)
	tableIds, err := utils.TextToUint64s(c.Query("tables"), ",")
	if err != nil {
		framework.MoLogger.Error("批量生成代码失败", zap.Error(err))
		response.FailMsgAsI18n(c, consts.ValidatorParamsCheckFailCode, consts.TKey_GormBatchGenCodeFailMsg)
		return
	}
	if buffer, err := services.ServiceGroupInst.ToolGroupInst.CodeGenServiceInst.BatchGenCode(bizId, tableIds); err != nil {
		framework.MoLogger.Error("批量生成代码失败", zap.Error(err))
		response.FailErrorWithCodeAsI18n(c, err, consts.CommSelectFailCode, consts.TKey_GormBatchGenCodeFailMsg)
		return
	} else {
		response.SuccessWithFileData(c, fmt.Sprintf(consts2.GenCode_Zip_FileName, time.Now().Unix()), buffer)
	}
}

func (g *CodeGenCtrl) SyncDb(c *gin.Context) {
	importTableReq := &tool.ImportTableReq{}
	if err := c.ShouldBindQuery(importTableReq); err != nil {
		framework.MoLogger.Error("同步表失败", zap.Error(err))
		response.FailMsgAsI18n(c, consts.ValidatorParamsCheckFailCode, consts.TKey_GormImportTableFailMsg)
		return
	}
	importTableReq.BizId = utils.StrToUint64Def(c.Param("bizId"), 0)
	username := utils.GetUsernameFromGin(c)
	if err := services.ServiceGroupInst.ToolGroupInst.CodeGenServiceInst.SyncDb(importTableReq, username); err != nil {
		framework.MoLogger.Error("同步表失败", zap.Error(err))
		response.FailMsgAsI18n(c, consts.CommSelectFailCode, consts.TKey_GormImportTableFailMsg)
		return
	}
	response.SuccessAsI18n(c, consts.TKey_GormImportTableSuccessMsg, nil)
}
